Completed
Push — master ( 1c048a...d412e6 )
by Dimas
08:15
created

gulpfile.ts ➔ createApp   A

Complexity

Conditions 3

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 26
dl 0
loc 37
rs 9.256
c 0
b 0
f 0
1
import * as gulp from "gulp";
2
import ts from "gulp-typescript";
3
import rename from "gulp-rename";
4
import * as fs from "fs";
5
import config from "../compiler/config";
6
import upath from "upath";
7
import path from "path";
8
import framework from "../compiler/index";
9
import log from "../compiler/log";
10
import process from "../compiler/process";
11
import core from "./core";
12
const root = process.root;
13
import sass from "sass"; // or require('node-sass');
14
import { exec, ExecException } from "child_process";
15
import sourcemaps from "gulp-sourcemaps";
16
import concat from "gulp-concat";
17
import uglify from "gulp-uglify";
18
import { localStorage } from "../node-localstorage/index";
19
import browserify from "browserify";
20
import browserify_source from "vinyl-source-stream";
21
import { fixDeps } from "./func";
22
localStorage.removeItem("compile");
23
console.clear();
24
25
/**
26
 * Build to /src/MVC/themes/assets/js/app.js
27
 * Minify Views Assets
28
 */
29
gulp.task("build", function () {
30
  return build();
31
});
32
33
gulp.task("build-clear", function () {
34
  return build(true);
35
});
36
37
/**
38
 * Build Project
39
 * @param withoutApp
40
 */
41
function build(withoutApp?: boolean) {
42
  try {
43
    var packageJson = root + "/package.json";
44
    if (fs.existsSync(packageJson)) {
45
      var json_pkg = JSON.parse(fs.readFileSync(packageJson).toString());
46
      fixDeps(json_pkg).then(function (json) {
47
        fs.writeFileSync(
48
          root + "/package.json",
49
          JSON.stringify(json, null, 2),
50
          {
51
            encoding: "utf-8",
52
          }
53
        );
54
      });
55
    }
56
  } catch (error) {}
57
  return createApp(withoutApp ? true : false);
58
}
59
60
// watch libs/js/**/* and views
61
gulp.task("watch", function () {
62
  console.clear();
63
  const files = [
64
    "./libs/js/**/*",
65
    "./libs/src/**/*",
66
    "./src/MVC/**/*",
67
    "./etc/**/*",
68
    "./" + config.app.views + "/**/*",
69
  ];
70
  log.log(
71
    log.random("Listening ") +
72
      files
73
        .map(function (item) {
74
          return log.random(upath.resolve(item));
75
        })
76
        .join(" ")
77
  );
78
79
  var compiler_runner: any = false;
80
  var run_watch = gulp
81
    .watch(files, null)
82
    .on("change", function (
83
      file: string | Buffer | import("url").URL | string[]
84
    ) {
85
      const trigger = function () {
86
        file = framework.normalize(path.resolve(file.toString()));
87
        /**
88
         * Check is library compiler or source compiler
89
         */
90
        const is_Lib = /libs\/(js|src)\//s.test(framework.normalize(file));
91
        const filename_log = framework.filelog(file);
92
93
        if (is_Lib) {
94
          var isCompiler = file.includes("/libs/compiler/");
95
          var isFramework = /((framework|app)\.(js|js.map)|\.map)$/s.test(file);
96
          if (isCompiler || isFramework) return;
97
          //console.log(file, isFramework);
98
          log.log(
99
            log.random("Library compiler triggered by ") +
100
              log.random(framework.filelog(file))
101
          );
102
          log.log(
103
            log
104
              .chalk()
105
              .yellow(`start compile ${log.random("src/MVC/themes/assets/js")}`)
106
          );
107
          if (compiler_runner) {
108
            log.log(log.error("Compiler still running"));
109
          } else {
110
            compiler_runner = setTimeout(function () {
111
              createApp(true);
112
              compiler_runner = null;
113
            }, 5000);
114
          }
115
        } else {
116
          if (/\.(js|scss|css)$/s.test(file)) {
117
            if (!/\.min\.(js|css)$/s.test(file)) {
118
              minify(file);
119
            }
120
          } else if (file.endsWith(".ts") && !file.endsWith(".d.ts")) {
121
            if (!/libs\/|libs\\/s.test(file)) {
122
              single_tsCompile(file);
123
            }
124
          } else {
125
            var reason = log.error(undefined);
126
            if (/\.(php|log|txt|htaccess)$/s.test(filename_log)) {
127
              reason = log.random("excluded");
128
            }
129
            log.log(`[${reason}] cannot modify ${log.random(filename_log)}`);
130
          }
131
        }
132
      };
133
      return trigger();
134
    });
135
  return run_watch;
136
});
137
138
gulp.task("assets-compile", function () {
139
  function filter(views: any[]) {
140
    return views
141
      .filter(function (item) {
142
        return (
143
          /\.(js|scss|css|sass|less)$/.test(item) &&
144
          !/\.min\.(js|css)$/.test(item) &&
145
          !/\-ori|\-original|\-backup|\.bak/s.test(item)
146
        );
147
      })
148
      .map(function (asset) {
149
        return framework.normalize(asset);
150
      });
151
  }
152
  var css = framework.readdir(root + "/assets/css");
153
  css = filter(css);
154
  var js = framework.readdir(root + "/assets/js");
155
  js = filter(js);
156
});
157
158
gulp.task("default", gulp.series(["build", "watch"]));
159
160
/**
161
 * NodeJS to Browserify
162
 * @param target source javascript
163
 * @param destination destination folder
164
 * @param rename want to rename file ? give name or using default basename of target
165
 */
166
function node2browser(target?: string, destination?: string, rename?: string) {
167
  if (typeof rename != "string" || !rename || !rename.length) {
168
    rename = path.basename(target);
169
  }
170
171
  log.log(
172
    `Browserify ${log
173
      .chalk()
174
      .magentaBright(framework.filelog(target))} to ${log
175
      .chalk()
176
      .magentaBright(framework.filelog(destination))} renamed to ${log.success(
177
      rename
178
    )}`
179
  );
180
  return (
181
    browserify()
182
      .add(target) //"src/MVC/themes/assets/js/app.js"
183
      .bundle()
184
      //Pass desired output filename to vinyl-source-stream
185
      .pipe(browserify_source(rename)) //"app.js"
186
      // Start piping stream to tasks!
187
      .pipe(gulp.dest(destination))
188
  ); //"src/MVC/themes/assets/js/"
189
}
190
191
/**
192
 * minify assets
193
 * @param file
194
 */
195
export function minify(item: string | Buffer) {
196
  const exists = fs.existsSync(item);
197
  if (exists) {
198
    item = item.toString();
199
    var config:
200
      | string
201
      | {
202
          obfuscate: boolean;
203
        } = upath.normalizeSafe(
204
      root + "/src/MVC/config/" + item.replace(framework.root(), "")
205
    );
206
    config = framework.normalize(framework.root() + config);
207
    config = config.replace(/\.(js|css)/s, ".json");
208
    if (fs.existsSync(config)) {
209
      config = require(config);
210
    }
211
    if (item.endsWith(".scss") && !item.endsWith(".min.scss")) {
212
      framework.scss(item);
213
    } else if (item.endsWith(".css") && !item.endsWith(".min.css")) {
214
      framework.minCSS(item);
215
    } else if (item.endsWith(".js") && !item.endsWith(".min.js")) {
216
      if (!item.endsWith(".babel.js")) {
217
        framework.minJS(item);
218
        var deleteObfuscated = false;
219
        if (typeof config == "object") {
220
          if (config.hasOwnProperty("obfuscate")) {
221
            if (config.obfuscate) {
222
              framework.obfuscate(item);
223
            } else {
224
              deleteObfuscated = true;
225
            }
226
          } else {
227
            deleteObfuscated = true;
228
          }
229
        }
230
        if (deleteObfuscated) {
231
          var obfuscatedjs = item.replace(/\.js$/s, ".obfuscated.js");
232
          var obfuscatedminjs = item.replace(/\.js$/s, ".obfuscated.min.js");
233
          framework.unlink(obfuscatedjs);
234
          framework.unlink(obfuscatedminjs);
235
        }
236
      }
237
    } else if (item.endsWith(".ts") && !item.endsWith(".d.ts")) {
238
      if (!/libs\/|libs\\/s.test(item)) {
239
        single_tsCompile(item);
240
      }
241
    }
242
  }
243
}
244
245
/**
246
 * List views folder
247
 */
248
export function views() {
249
  var views = framework.readdir(root + `/${config.app.views}`);
250
  return views
251
    .filter(function (item) {
252
      return (
253
        /\.(js|scss|css|sass|less)$/.test(item) &&
254
        !/\.min\.(js|css)$/.test(item) &&
255
        !/\-ori|\-original|\-backup|\.bak/s.test(item)
256
      );
257
    })
258
    .map(function (asset) {
259
      return framework.normalize(asset);
260
    });
261
}
262
263
/**
264
 * minify multiple assets
265
 * @param assets
266
 */
267
export function multiMinify(assets: any[]) {
268
  assets.map(minify);
269
}
270
271
localStorage.removeItem("compile");
272
/**
273
 * Create App.js
274
 * @param withoutView false to not compile views javascripts
275
 */
276
export async function createApp(withoutView: boolean) {
277
  var exists = localStorage.getItem("compile");
278
  if (!exists) {
279
    localStorage.setItem("compile", "running");
280
    var target = upath.normalizeSafe(
281
      upath.resolve(upath.join(root, "src/MVC/themes/assets/js/app.js"))
282
    );
283
    await typescriptCompiler("tsconfig.build.json", root + "/").catch(function (
284
      err
285
    ) {
286
      log.log(log.error(err));
287
    });
288
    await typescriptCompiler("tsconfig.precompiler.json", root + "/").catch(
289
      function (err) {
290
        log.log(log.error(err));
291
      }
292
    );
293
    await typescriptCompiler("tsconfig.compiler.json", root + "/libs/").catch(
294
      function (err) {
295
        log.log(log.error(err));
296
      }
297
    );
298
    minify(target);
299
    if (!withoutView) {
300
      multiMinify(views());
301
    }
302
    localStorage.removeItem("compile");
303
    //node2browser(target, path.dirname(target));
304
  } else {
305
    log.log(
306
      log.error("Compiler lock process already exists ") +
307
        log.chalk().yellow("node index.js fix") +
308
        log.chalk().green(" to fix it")
309
    );
310
  }
311
}
312
313
/**
314
 * Single Typescript Compiler
315
 * @param target
316
 * @todo universal-framework typescript compiler support
317
 */
318
export function single_tsCompile(target: string) {
319
  var targetlog = log.chalk().magentaBright(framework.filelog(target));
320
  if (target.endsWith(".d.ts")) {
321
    log.log(`${targetlog} is declaration file`);
322
    return;
323
  }
324
  var dest = path.dirname(target);
325
  var filename = path.basename(target);
326
  log.log(
327
    `${targetlog} > ${log
328
      .chalk()
329
      .yellow(framework.filelog(target.replace(/\.ts$/, ".js")))} start`
330
  );
331
  var tsProject = ts.createProject({
332
    declaration: false,
333
    skipLibCheck: true,
334
  });
335
  return gulp.src(target).pipe(tsProject()).pipe(gulp.dest(dest));
336
}
337
338
/**
339
 * Typescript compiler
340
 * @param source
341
 * @param destination
342
 * @param callback
343
 */
344
export function typescriptCompiler(
345
  source: string,
346
  destination: string,
347
  callback: (arg0: any, arg1: any) => void = null
348
) {
349
  return new Promise((resolve, reject) => {
350
    exec(`tsc -p ${source}`, function (
351
      err: ExecException,
352
      stdout: string,
353
      stderr: string
354
    ) {
355
      if (!err) {
356
        if (typeof callback == "function") {
357
          callback(source, destination);
358
        }
359
        if (stdout.trim().length) {
360
          console.log(stdout);
361
        }
362
        if (stderr.trim().length) {
363
          console.log(stderr);
364
        }
365
        log.log(
366
          log.random("successfully compiled ") +
367
            log.success(path.basename(source))
368
        );
369
        resolve();
370
      } else {
371
        log.log(
372
          log.random("failed compile ") + log.error(path.basename(source))
373
        );
374
        reject(err.message);
375
      }
376
    });
377
  });
378
}
379